import { AxiosError } from "axios";
import { useMessage } from "naive-ui";
import { isErrorResult, isUnAuthResult, isWarningResult } from "@/api/utils.ts";

const HTTP_CODE_MAP: { [p: number]: string } = {
    400: "请求缺少参数",
    404: "错误的请求地址",
    405: "不被支持的请求类型",
    500: "服务器内部错误",
}

export function handleAjaxError<E>(error: E): E {
    console.debug("ajax.error", error);
    if (error instanceof AxiosError && error.isAxiosError) {
        // Axios请求/响应错误
        if (error.response?.status) {
            message?.error(HTTP_CODE_MAP[error.response.status] || error.message);
        }
    } else if (error instanceof ApiError) {
        // Axios请求/响应成功, 但是后端响应结果不是成功
        if (isWarningResult(error.code)) {
            message?.warning(error.message);
        } else if (isErrorResult(error.code)) {
            message?.error(error.message);
        } else if (isUnAuthResult(error.code)) {
            message?.error(error.message || "需要登录");
        }
    } else if (error instanceof Error) {
        // 其它错误
        message?.error(error.message);
    } else {
        // 未知的数据类型暂时不提示出去
    }

    return error;
}


/**
 * API响应错误, 代表后端响应的code并非成功
 */
export class ApiError extends Error {
    code: number;
    constructor(code: number, msg: string) {
        super(msg);
        this.code = code;
    }
}


/*
    在Axios拦截器中自动进行消息提示需要使用到Message组件, 但是该组件只有在App内使用useMessage可以获得
    所以在这里导出一个设置方法, 在App内拿到Message组件时设置进来这里就可以使用了
 */

let message: ReturnType<typeof useMessage> | null = null;
export function setMessageComponent(component: typeof message) {
    message = component;
}